home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / binutils.7 / binutils / binutils-2.7 / gas / stabs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-07-04  |  11.1 KB  |  458 lines

  1. /* Generic stabs parsing for gas.
  2.    Copyright (C) 1989, 90, 91, 93, 94, 95, 1996 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as
  8. published by the Free Software Foundation; either version 2,
  9. or (at your option) any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful, but
  12. WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
  14. the GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to the Free
  18. Software Foundation, 59 Temple Place - Suite 330, Boston, MA
  19. 02111-1307, USA. */
  20.  
  21. #include "as.h"
  22. #include "libiberty.h"
  23. #include "obstack.h"
  24. #include "subsegs.h"
  25. #include "ecoff.h"
  26.  
  27. /* We need this, despite the apparent object format dependency, since
  28.    it defines stab types, which all object formats can use now. */
  29.  
  30. #include "aout/stab_gnu.h"
  31.  
  32. /* Allow backends to override the names used for the stab sections.  */
  33. #ifndef STAB_SECTION_NAME
  34. #define STAB_SECTION_NAME ".stab"
  35. #endif
  36.  
  37. #ifndef STAB_STRING_SECTION_NAME
  38. #define STAB_STRING_SECTION_NAME ".stabstr"
  39. #endif
  40.  
  41. /*
  42.  * Handle .stabX directives, which used to be open-coded.
  43.  * So much creeping featurism overloaded the semantics that we decided
  44.  * to put all .stabX thinking in one place. Here.
  45.  *
  46.  * We try to make any .stabX directive legal. Other people's AS will often
  47.  * do assembly-time consistency checks: eg assigning meaning to n_type bits
  48.  * and "protecting" you from setting them to certain values. (They also zero
  49.  * certain bits before emitting symbols. Tut tut.)
  50.  *
  51.  * If an expression is not absolute we either gripe or use the relocation
  52.  * information. Other people's assemblers silently forget information they
  53.  * don't need and invent information they need that you didn't supply.
  54.  */
  55.  
  56. /*
  57.  * Build a string dictionary entry for a .stabX symbol.
  58.  * The symbol is added to the .<secname>str section.
  59.  */
  60.  
  61. #ifndef SEPARATE_STAB_SECTIONS
  62. #define SEPARATE_STAB_SECTIONS 0
  63. #endif
  64.  
  65. unsigned int
  66. get_stab_string_offset (string, stabstr_secname)
  67.      const char *string;
  68.      const char *stabstr_secname;
  69. {
  70.   unsigned int length;
  71.   unsigned int retval;
  72.  
  73.   if (! SEPARATE_STAB_SECTIONS)
  74.     abort ();
  75.  
  76.   retval = 0;
  77.   length = strlen (string);
  78.   if (length > 0)
  79.     {                /* Ordinary case. */
  80.       segT save_seg;
  81.       subsegT save_subseg;
  82.       segT seg;
  83.       char *p;
  84.  
  85.       save_seg = now_seg;
  86.       save_subseg = now_subseg;
  87.  
  88.       /* Create the stab string section.  */
  89.       seg = subseg_new (stabstr_secname, 0);
  90.  
  91.       retval = seg_info (seg)->stabu.stab_string_size;
  92.       if (retval <= 0)
  93.     {
  94.       /* Make sure the first string is empty.  */
  95.       p = frag_more (1);
  96.       *p = 0;
  97.       retval = seg_info (seg)->stabu.stab_string_size = 1;
  98. #ifdef BFD_ASSEMBLER
  99.       bfd_set_section_flags (stdoutput, seg, SEC_READONLY | SEC_DEBUGGING);
  100.       if (seg->name == stabstr_secname)
  101.         seg->name = xstrdup (stabstr_secname);
  102. #endif
  103.     }
  104.  
  105.       p = frag_more (length + 1);
  106.       strcpy (p, string);
  107.  
  108.       seg_info (seg)->stabu.stab_string_size += length + 1;
  109.  
  110.       subseg_set (save_seg, save_subseg);
  111.     }
  112.  
  113.   return retval;
  114. }
  115.  
  116. #ifdef AOUT_STABS
  117. #ifndef OBJ_PROCESS_STAB
  118. #define OBJ_PROCESS_STAB(SEG,W,S,T,O,D)    aout_process_stab(W,S,T,O,D)
  119. #endif
  120.  
  121. static void
  122. aout_process_stab (what, string, type, other, desc)
  123.      int what;
  124.      const char *string;
  125.      int type, other, desc;
  126. {
  127.   /* Put the stab information in the symbol table.  */
  128.   symbolS *symbol;
  129.  
  130.   /* Create the symbol now, but only insert it into the symbol chain
  131.      after any symbols mentioned in the value expression get into the
  132.      symbol chain.  This is to avoid "continuation symbols" (where one
  133.      ends in "\" and the debug info is continued in the next .stabs
  134.      directive) from being separated by other random symbols.  */
  135.   symbol = symbol_create (string, undefined_section, 0,
  136.               (struct frag *) NULL);
  137.   if (what == 's' || what == 'n')
  138.     {
  139.       /* Pick up the value from the input line.  */
  140.       symbol->sy_frag = &zero_address_frag;
  141.       pseudo_set (symbol);
  142.     }
  143.   else
  144.     {
  145.       /* .stabd sets the name to NULL.  Why?  */
  146.       S_SET_NAME (symbol, NULL);
  147.       symbol->sy_frag = frag_now;
  148.       S_SET_VALUE (symbol, (valueT) frag_now_fix ());
  149.     }
  150.  
  151.   symbol_append (symbol, symbol_lastP, &symbol_rootP, &symbol_lastP);
  152.  
  153.   S_SET_TYPE (symbol, type);
  154.   S_SET_OTHER (symbol, other);
  155.   S_SET_DESC (symbol, desc);
  156. }
  157. #endif
  158.  
  159. /* This can handle different kinds of stabs (s,n,d) and different
  160.    kinds of stab sections. */
  161.  
  162. static void 
  163. s_stab_generic (what, stab_secname, stabstr_secname)
  164.      int what;
  165.      char *stab_secname;
  166.      char *stabstr_secname;
  167. {
  168.   long longint;
  169.   char *string;
  170.   int type;
  171.   int other;
  172.   int desc;
  173.  
  174.   /* The general format is:
  175.      .stabs "STRING",TYPE,OTHER,DESC,VALUE
  176.      .stabn TYPE,OTHER,DESC,VALUE
  177.      .stabd TYPE,OTHER,DESC
  178.      At this point input_line_pointer points after the pseudo-op and
  179.      any trailing whitespace.  The argument what is one of 's', 'n' or
  180.      'd' indicating which type of .stab this is.  */
  181.  
  182.   if (what != 's')
  183.     string = "";
  184.   else
  185.     {
  186.       int length;
  187.  
  188.       string = demand_copy_C_string (&length);
  189.       SKIP_WHITESPACE ();
  190.       if (*input_line_pointer == ',')
  191.     input_line_pointer++;
  192.       else
  193.     {
  194.       as_warn (".stabs: Missing comma");
  195.       ignore_rest_of_line ();
  196.       return;
  197.     }
  198.     }
  199.  
  200.   if (get_absolute_expression_and_terminator (&longint) != ',')
  201.     {
  202.       as_warn (".stab%c: Missing comma", what);
  203.       ignore_rest_of_line ();
  204.       return;
  205.     }
  206.   type = longint;
  207.  
  208.   if (get_absolute_expression_and_terminator (&longint) != ',')
  209.     {
  210.       as_warn (".stab%c: Missing comma", what);
  211.       ignore_rest_of_line ();
  212.       return;
  213.     }
  214.   other = longint;
  215.  
  216.   desc = get_absolute_expression ();
  217.   if (what == 's' || what == 'n')
  218.     {
  219.       if (*input_line_pointer != ',')
  220.     {
  221.       as_warn (".stab%c: Missing comma", what);
  222.       ignore_rest_of_line ();
  223.       return;
  224.     }
  225.       input_line_pointer++;
  226.       SKIP_WHITESPACE ();
  227.     }
  228.  
  229. #ifdef TC_PPC
  230. #ifdef OBJ_ELF
  231.   /* Solaris on PowerPC has decided that .stabd can take 4 arguments, so if we were
  232.      given 4 arguments, make it a .stabn */
  233.   else if (what == 'd')
  234.     {
  235.       char *save_location = input_line_pointer;
  236.  
  237.       SKIP_WHITESPACE ();
  238.       if (*input_line_pointer == ',')
  239.     {
  240.       input_line_pointer++;
  241.       what = 'n';
  242.     }
  243.       else
  244.     input_line_pointer = save_location;
  245.     }
  246. #endif /* OBJ_ELF */
  247. #endif /* TC_PPC */
  248.  
  249. #ifndef NO_LISTING
  250.   if (listing)
  251.     {
  252.       switch (type)
  253.     {
  254.     case N_SLINE:
  255.       listing_source_line ((unsigned int) desc);
  256.       break;
  257.     case N_SO:
  258.     case N_SOL:
  259.       listing_source_file (string);
  260.       break;
  261.     }
  262.     }
  263. #endif /* ! NO_LISTING */
  264.  
  265.   /* We have now gathered the type, other, and desc information.  For
  266.      .stabs or .stabn, input_line_pointer is now pointing at the
  267.      value.  */
  268.  
  269.   if (SEPARATE_STAB_SECTIONS)
  270.     /* Output the stab information in a separate section.  This is used
  271.        at least for COFF and ELF.  */
  272.     {
  273.       segT saved_seg = now_seg;
  274.       subsegT saved_subseg = now_subseg;
  275.       fragS *saved_frag = frag_now;
  276.       valueT dot;
  277.       segT seg;
  278.       unsigned int stroff;
  279.       char *p;
  280.  
  281.       static segT cached_sec;
  282.       static char *cached_secname;
  283.  
  284.       dot = frag_now_fix ();
  285.  
  286.       if (cached_secname && !strcmp (cached_secname, stab_secname))
  287.     {
  288.       seg = cached_sec;
  289.       subseg_set (seg, 0);
  290.     }
  291.       else
  292.     {
  293.       seg = subseg_new (stab_secname, 0);
  294.       if (cached_secname)
  295.         free (cached_secname);
  296.       cached_secname = xstrdup (stab_secname);
  297.       cached_sec = seg;
  298.     }
  299.  
  300.       if (! seg_info (seg)->hadone)
  301.     {
  302. #ifdef BFD_ASSEMBLER
  303.       bfd_set_section_flags (stdoutput, seg,
  304.                  SEC_READONLY | SEC_RELOC | SEC_DEBUGGING);
  305. #endif
  306. #ifdef INIT_STAB_SECTION
  307.       INIT_STAB_SECTION (seg);
  308. #endif
  309.       seg_info (seg)->hadone = 1;
  310.     }
  311.  
  312.       stroff = get_stab_string_offset (string, stabstr_secname);
  313.       if (what == 's')
  314.     {
  315.       /* release the string */
  316.       obstack_free (¬es, string);
  317.     }
  318.  
  319.       /* At least for now, stabs in a special stab section are always
  320.      output as 12 byte blocks of information.  */
  321.       p = frag_more (8);
  322.       md_number_to_chars (p, (valueT) stroff, 4);
  323.       md_number_to_chars (p + 4, (valueT) type, 1);
  324.       md_number_to_chars (p + 5, (valueT) other, 1);
  325.       md_number_to_chars (p + 6, (valueT) desc, 2);
  326.  
  327.       if (what == 's' || what == 'n')
  328.     {
  329.       /* Pick up the value from the input line.  */
  330.       cons (4);
  331.       input_line_pointer--;
  332.     }
  333.       else
  334.     {
  335.       const char *fake;
  336.       symbolS *symbol;
  337.       expressionS exp;
  338.  
  339.       /* Arrange for a value representing the current location.  */
  340.       fake = FAKE_LABEL_NAME;
  341.       symbol = symbol_new (fake, saved_seg, dot, saved_frag);
  342.  
  343.       exp.X_op = O_symbol;
  344.       exp.X_add_symbol = symbol;
  345.       exp.X_add_number = 0;
  346.  
  347.       emit_expr (&exp, 4);
  348.     }
  349.  
  350. #ifdef OBJ_PROCESS_STAB
  351.       OBJ_PROCESS_STAB (seg, what, string, type, other, desc);
  352. #endif
  353.  
  354.       subseg_set (saved_seg, saved_subseg);
  355.     }
  356.   else
  357.     {
  358. #ifdef OBJ_PROCESS_STAB
  359.       OBJ_PROCESS_STAB (0, what, string, type, other, desc);
  360. #else
  361.       abort ();
  362. #endif
  363.     }
  364.  
  365.   demand_empty_rest_of_line ();
  366. }
  367.  
  368. /* Regular stab directive. */
  369.  
  370. void
  371. s_stab (what)
  372.      int what;
  373. {
  374.   s_stab_generic (what, STAB_SECTION_NAME, STAB_STRING_SECTION_NAME);
  375. }
  376.  
  377. /* "Extended stabs", used in Solaris only now. */
  378.  
  379. void
  380. s_xstab (what)
  381.      int what;
  382. {
  383.   int length;
  384.   char *stab_secname, *stabstr_secname;
  385.   static char *saved_secname, *saved_strsecname;
  386.  
  387.   /* @@ MEMORY LEAK: This allocates a copy of the string, but in most
  388.      cases it will be the same string, so we could release the storage
  389.      back to the obstack it came from.  */
  390.   stab_secname = demand_copy_C_string (&length);
  391.   SKIP_WHITESPACE ();
  392.   if (*input_line_pointer == ',')
  393.     input_line_pointer++;
  394.   else
  395.     {
  396.       as_bad ("comma missing in .xstabs");
  397.       ignore_rest_of_line ();
  398.       return;
  399.     }
  400.  
  401.   /* To get the name of the stab string section, simply add "str" to
  402.      the stab section name.  */
  403.   if (saved_secname == 0 || strcmp (saved_secname, stab_secname))
  404.     {
  405.       stabstr_secname = (char *) xmalloc (strlen (stab_secname) + 4);
  406.       strcpy (stabstr_secname, stab_secname);
  407.       strcat (stabstr_secname, "str");
  408.       if (saved_secname)
  409.     {
  410.       free (saved_secname);
  411.       free (saved_strsecname);
  412.     }
  413.       saved_secname = stab_secname;
  414.       saved_strsecname = stabstr_secname;
  415.     }
  416.   s_stab_generic (what, saved_secname, saved_strsecname);
  417. }
  418.  
  419. #ifdef S_SET_DESC
  420.  
  421. /* Frob invented at RMS' request. Set the n_desc of a symbol.  */
  422.  
  423. void 
  424. s_desc (ignore)
  425.      int ignore;
  426. {
  427.   char *name;
  428.   char c;
  429.   char *p;
  430.   symbolS *symbolP;
  431.   int temp;
  432.  
  433.   name = input_line_pointer;
  434.   c = get_symbol_end ();
  435.   p = input_line_pointer;
  436.   *p = c;
  437.   SKIP_WHITESPACE ();
  438.   if (*input_line_pointer != ',')
  439.     {
  440.       *p = 0;
  441.       as_bad ("Expected comma after name \"%s\"", name);
  442.       *p = c;
  443.       ignore_rest_of_line ();
  444.     }
  445.   else
  446.     {
  447.       input_line_pointer++;
  448.       temp = get_absolute_expression ();
  449.       *p = 0;
  450.       symbolP = symbol_find_or_make (name);
  451.       *p = c;
  452.       S_SET_DESC (symbolP, temp);
  453.     }
  454.   demand_empty_rest_of_line ();
  455. }                /* s_desc() */
  456.  
  457. #endif /* defined (S_SET_DESC) */
  458.